import {
  asyncRoutes,
  constantRoutes
} from '@/router'

import Layout from '@/layout'

import {
  getRoutes
} from '@/api/role'

import { validatenull } from '@/utils/validate'
/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = {
      ...route
    }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({
    commit
  }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      getRoutes().then(res => {
        let data = getRouterRelation(res.data)
        if (roles.includes('admin')) {
          accessedRoutes = data || []
        } else {
          accessedRoutes = filterAsyncRoutes(data, roles)
        }
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      })

      // if (roles.includes('admin')) {
        
      //   accessedRoutes = asyncRoutes || []
      // } else {
      //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      // }
      // commit('SET_ROUTES', accessedRoutes)
      // resolve(accessedRoutes)
    })
  }
}


// 组装路由关系
function getRouterRelation(data) {
  const aRouter = []
  data.forEach(oMenu => {
    const {
      path,
      component,
      alwaysShow,
      name,
      meta,
      children
    } = oMenu

    const oRouter = {
      path: path,
      alwaysShow:alwaysShow,
      component:component=='Layout'?Layout:(resolve) => require([`@/${component}.vue`], resolve),
      name: name,
      meta: meta,
      children: validatenull(children) ? [] : getRouterRelation(children)
    }
    if (oRouter.children.length === 0) {
      delete oRouter.children
    }
    aRouter.push(oRouter)
  })
  return aRouter
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
